﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DigitalImage.softLib.stages;
using System.Drawing;

namespace DigitalImage.softLib {
    class CSoftLib {
        #region stages
        public List<IColorTransformation> colorTransformations {
            get;
            set;
        }
        public IColorToBinary colorToBinary {
            get;
            set;
        }
        public List<IBinaryTransformation> binaryTransformation {
            get;
            set;
        }
        public IRegionLabelling regionLabelling {
            get;
            set;
        }
        public INeuralNetwork neuralNetwork {
            get;
            set;
        }
        public IDictonaryCheck dictonaryCheck {
            get;
            set;
        }
        #endregion

        #region results
        public Bitmap firstStageResult{
            get;
            set;
        }
        public byte[,] secondStageResult{
            get;
            set;
        }
        public byte[,] thirdStageResult {
            get;
            set;
        }
        public List<List<CRasterRegion>> fourthStageResult {
            get;
            set;
        }
        public List<string> fifthStageResult {
            get;
            set;
        }
        #endregion

        public CSoftLib() {
            colorTransformations=new List<IColorTransformation>();
            colorToBinary=null;
            binaryTransformation=new List<IBinaryTransformation>();
            regionLabelling=null;
            neuralNetwork=null;
            dictonaryCheck=null;

        }

        #region AddTransformation
        public void addColorTransformation(IColorTransformation newTransformation) {
            colorTransformations.Add(newTransformation);
        }

        public void setColorToBinary(IColorToBinary newTransformation) {
            colorToBinary=newTransformation;
        }

        public void addBinaryTransformation(IBinaryTransformation newTransformation) {
            binaryTransformation.Add(newTransformation);
        }

        public void setRegionLabelling(IRegionLabelling newTransformation) {
            regionLabelling=newTransformation;
        }

        public void setNeuralNetwork(INeuralNetwork newTransformation) {
            neuralNetwork=newTransformation;
        }

        public void setDictonaryCheck(IDictonaryCheck newTransformation) {
            dictonaryCheck=newTransformation;
        }
        #endregion

        #region ExecuteTransformation
        public Bitmap executeColorTransformation(Bitmap input) {
            foreach(IColorTransformation transformation in colorTransformations) {
                input=transformation.transform(input);
            }
            firstStageResult=input;
            return input;
        }

        public byte[,] executeColorToBinary(Bitmap input) {
            byte[,] result;
            result=colorToBinary.transform(input);
            secondStageResult=result;
            return result;
        }

        public byte[,] executeBinaryTransformation(byte[,] input) {
            foreach(IBinaryTransformation transformation in binaryTransformation) {
                input=transformation.transform(input);
            }
            thirdStageResult=input;
            return input;
        }

        public List<List<CRasterRegion>> executeRegionLabelling(byte[,] input, bool train) {
            List<List<CRasterRegion>> result;
            result=regionLabelling.transform(input,train);
            fourthStageResult=result;
            return result;
        }

        public string executeDictonaryCheck(List<string> input) {
            string result;
            result=dictonaryCheck.transform(input);
            return result;
        }

        #endregion

        public void train(Bitmap image,List<string> trainMapper) {
            List<List<CRasterRegion>> preparedRegions = imageTransformation(image,true);
            neuralNetwork.train(preparedRegions, trainMapper);
        }

        public string execute(Bitmap image) {
            imageTransformation(image,false);

            fifthStageResult=new List<string>();
            string word;
            foreach(List<CRasterRegion> rowRegions in fourthStageResult){
                word="";
                foreach(CRasterRegion region in rowRegions) {
                    if (region.Equals(CRasterRegion.spaceRegion)) {
                        word += " ";
                    } else {
                        word += neuralNetwork.recognize(region);
                    }
                }
                //fifthStageResult.Add("\n");
                fifthStageResult.Add(word);
            }

            string result=executeDictonaryCheck(fifthStageResult);
            return result;
        }

        public List<List<CRasterRegion>> imageTransformation(Bitmap image, bool train) {
            executeColorTransformation(image);
            executeColorToBinary(firstStageResult);
            executeBinaryTransformation(secondStageResult);
            return executeRegionLabelling(thirdStageResult, train);
        }
    }
}
